#!/usr/bin/perl
# Jul 4, 2009 12:42:50 AM project management program

use strict;
#use warnings;
use IO::File;
use File::Find;

my $FILE_list = 'FILES.list';
my $root_dir = '/home/hideki/';


my $command = shift @ARGV;
my @targets_dir = @ARGV;
if(@targets_dir == 0){
	@targets_dir = qw(src out analysis);
}
if($command eq 'help'){
	&help();
}elsif($command eq 'project'){
	&project();
}elsif($command eq 'create'){
	&create();
}elsif($command eq 'update'){
	&update();
}elsif($command eq 'list'){
	&list();
}else{
	&help();
}
die "\n";


sub create{
	system("echo '=====' > $FILE_list");
	&update();
}

sub project{
	unless(-e "src"){
		mkdir "src", 0777, or die "mkidr error:$!";
		mkdir "bin", 0777, or die "mkdir error:$!";
		mkdir "out", 0777, or die "mkdir error:$!";
		mkdir "lib", 0777, or die "mkidr error:$!";
		mkdir "log", 0777, or die "mkdir error:$!";
		mkdir "sh", 0777, or die "mkdir error:$!";
		mkdir "analysis", 0777, or die "mkdir error:$!";
	}
	foreach my $dir(qw(src out analysis)){
		system("echo '=====' > $dir/$FILE_list");
	}
	&update();
}

sub update{
	my ($target_place) = @_;
	if($target_place eq "" and -e "src" and -e "out" and -e "analysis"){
		chomp (my $parent = `pwd`);
		&update("$parent/src");
		&update("$parent/out");
		&update("$parent/analysis");
		return;
	}elsif($target_place eq "" and -e $FILE_list){
		chomp ($target_place = `pwd`);
	}elsif($target_place eq ""){
		chomp ($target_place = `pwd`);
		if($target_place =~ m/(src|out|analysis)$/){
			system("echo '=====' > $FILE_list");
		}else{
			die "cannot find $FILE_list file\n";
		}
	}

	### reading $FILE_list
	my $fh_FILE = IO::File->new("$target_place/$FILE_list") or die "cannot open $target_place/$FILE_list: $!";
	$fh_FILE->getline();
	my %list;
	while($_ = $fh_FILE->getline()){
		chomp;
		my @data = split / \: /;
		if(@data == 2){
			$list{$data[0]} = $data[1];
		}elsif(@data == 1){
			$list{$data[0]} = "";
		}
	}
	$fh_FILE->close();

	### making the list of existing files
	my %exist_list;
	opendir (DIR, $target_place) or die "opendir error $target_place:$!";
	while(my $entry = readdir DIR){
		my $day = (stat($entry))[9];
		if($entry eq $FILE_list or $entry =~ m/^\./ or -d $entry or $entry =~ m/\~$/){
			next;
		}else{
			$exist_list{$entry} = $day;
		}
	}
	closedir DIR;

    my $flag_modify = 0;

	### write list file
	my $fh_out = IO::File->new("$target_place/$FILE_list", 'w') or die "cannot write $target_place/$FILE_list: $!";
	(my $current_place = $target_place) =~ s|/home/hideki|~|;
	$fh_out->print("$current_place\n");
	foreach my $key (sort {$exist_list{$b} <=> $exist_list{$a}} keys %exist_list){
		# if directory is "src" get the comment from each program
		if($current_place =~ m/src$/){
			$fh_out->print("$key : ".&get_program_comment("$target_place/$key")."\n");
			delete $list{$key};
		}else{
			if(exists $list{$key}){
				$fh_out->print("$key : $list{$key}\n");
				delete $list{$key};
			}else{
				$fh_out->print("$key : \n");
				$flag_modify = 1;
			}
		}
	}

	# missing file
	$fh_out->print("\n");
	foreach my $key (keys %list){
		my $explain = $list{$key};
		$key =~ s/^\?+//;
		$fh_out->print("?$key : $explain\n");
		$flag_modify = 1;
	}

	$fh_out->close();

	if($flag_modify == 1){
		system("emacs $target_place/$FILE_list");
	}
}

sub get_program_comment{
	my ($file) = @_;
	my $fh = IO::File->new($file) or die "cannot open $file: $!";
	my $comment = "";
	while($_ = $fh->getline()){
		s/\r?\n//;
		if(m/^\#\!/){
		    next;
		}
		if(m/^\#/){
			$comment = $_;
			$comment =~ s/^\# ?//;
#			$comment =~ s|^[\/\d\-]+ ||;
			last;
		}
	}
	$fh->close();
	return $comment;
}


sub list{
	find(\&treatment, $root_dir);
}

sub treatment{
	foreach my $folder(@targets_dir){
		if($File::Find::dir =~ m/$folder$/ and $_ eq $FILE_list){
			my $fh_log = IO::File->new($File::Find::name) or die "cannot open $File::Find::name: $!";
			chomp (my $currentDir = $fh_log->getline());
			while($_ = $fh_log->getline()){
				chomp;
				if($_ ne ''){
					print "$currentDir : $_\n";
				}
			}
			$fh_log->close();
		}
	}
}

sub help{
		print <<"EOF";
create	: make FILES.list
project	: making project (make FILES.list, src out analysis bin lib folder)
update	: update current position and file list
list [src/out/analysis]	: display the all FILES.list files contents
EOF
}
